﻿
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text.Json;
using Dapper;
using K9Nano.Exceptions;
using K9Nano.FileStorage;
using Microsoft.Extensions.Logging;
using MiniExcelLibs;
using MiniExcelLibs.OpenXml;

namespace K9Nano.Reporting.Dapper.Internals;

internal class DapperReportEngine(IReportingEngineConnectionFactory factory, IFileStorage fileStorage, ILogger<DapperReportEngine> logger) : IReportEngine
{
    public async Task<ReportResult> ExectueAsync(Report report, IReadOnlyDictionary<string, object> reportParameters, CancellationToken cancellation)
    {
        using var connection = factory.Create();

        DynamicParameters parameter = new();

        foreach (var (key, value) in reportParameters)
        {
            logger.LogDebug("报表参数：{Key}, 参数值：{Value}", key, value);
            parameter.Add(key, value);
        }

        var total = await connection.QueryFirstOrDefaultAsync<int>(report.TotalSqlText, parameter);
        if (total <= 0)
        {
            return new ReportResult(0, null);
        }

        var items = await connection.QueryAsync(report.SqlText, parameter);
        return new ReportResult(total, items);
    }

    public async Task<string> ExportAsync(Report report, IReadOnlyDictionary<string, object> reportParameters, CancellationToken cancellation)
    {
        using var connection = factory.Create();

        DynamicParameters parameter = new();

        foreach (var (key, value) in reportParameters)
        {
            logger.LogDebug("报表参数：{Key}, 参数值：{Value}", key, value);
            parameter.Add(key, value);
        }

        //// 创建表头，作为模板数据
        //var templateFile = fileStorage.GetTmpFile(".xlsx");
        //var columnNames = report.Columns.ToDictionary(a => a.DisplayName, a => "{{" + a.Name + "}}");
        //MiniExcel.SaveAs(templateFile, new Dictionary<string, string>[] { columnNames });
        //var dataReader = await connection.ExecuteReaderAsync(report.SqlText, parameter);
        //var resultFile = fileStorage.GetTmpFile(".xlsx");
        // 异常：Parameters count mismatch
        //await MiniExcel.SaveAsByTemplateAsync(resultFile, templateFile, dataReader, cancellationToken: cancellation);

        // TODO 使用DataTable会将数据全部读入内存，待优化
        var table = new DataTable();
        var dataReader = await connection.ExecuteReaderAsync(report.SqlText, parameter);
        table.Load(dataReader);
        foreach (DataColumn col in table.Columns)
        {
            if(report.Columns.FirstOrDefault(a=>a.Name == col.ColumnName) is ReportColumn reportCol)
            {
                col.ColumnName = reportCol.DisplayName;
            }
        }
        var resultFile = fileStorage.GetTmpFile(".xlsx");
        await MiniExcel.SaveAsAsync(resultFile, table, cancellationToken: cancellation);

        return resultFile;
    }
}

